package com.hncc.kumao.tool;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.commons.io.output.CountingOutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import com.hncc.kumao.entity.BreakpointUploadTask;
import com.hncc.kumao.entity.NetdiskAccessToken;
import com.hncc.kumao.entity.OfflineDownloadTask;
import com.hncc.kumao.exception.KumaoException;
import com.hncc.kumao.exception.KumaoNetdiskFileNotFoundException;
import com.hncc.kumao.util.ConstValue;
import com.hncc.kumao.util.EncodeUtils;
import com.hncc.kumao.util.MyDownloadProgress;
import com.hncc.kumao.util.OfflineDownloadUtils;


public class FTPOperation {

    private static String taskId;

    /**
     * 检查当前网盘信息是否有效
     * @param netdiskAccessToken 网盘信息
     * @return
     */
    public static boolean check(NetdiskAccessToken netdiskAccessToken) {
        FTPClient ftpClient = null;
        boolean exists = false;
        try {
            String netdiskUrl = netdiskAccessToken.getNetdiskUrl();
            netdiskUrl = netdiskUrl.replace("ftp://", "");
            String[] urlContent = netdiskUrl.split(":");
            ftpClient = new FTPClient();
            ftpClient.setConnectTimeout(10000);
            ftpClient.connect(urlContent[0], Integer.parseInt(urlContent[1]));
            //判断是匿名访问还是用户名密码
            if(netdiskAccessToken.getTokenType() == ConstValue.TOKEN_TYPE_USERNAME_PASSWORD) {
                //用户名密码登录
                exists = ftpClient.login(netdiskAccessToken.getUsername(), netdiskAccessToken.getPassword());
            } else {
                //匿名访问，用户名密码随便给一个
                exists = ftpClient.login("anonymous", "anonymous");                
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } 
        return exists;
    }
    
    //下载文件
    public static void download(final OfflineDownloadTask offlineDownloadTask, NetdiskAccessToken netdiskAccessToken,
            final MyDownloadProgress progress) throws Exception {
        FTPClient ftpClient = null;
        FileOutputStream fos = null;
        try {
            taskId = offlineDownloadTask.getId();
            String fileUri = offlineDownloadTask.getFileUri();
            String encodeFileUri = EncodeUtils.encodeFTPPath(fileUri);
            
            String netdiskUrl = netdiskAccessToken.getNetdiskUrl();
            netdiskUrl = netdiskUrl.replace("ftp://", "");
            String[] urlContent = netdiskUrl.split(":");
            ftpClient = new FTPClient();
            ftpClient.connect(urlContent[0], Integer.parseInt(urlContent[1]));
            
            //判断是匿名访问还是用户名密码
            if(netdiskAccessToken.getTokenType() == ConstValue.TOKEN_TYPE_USERNAME_PASSWORD) {
                //用户名密码登录
                ftpClient.login(netdiskAccessToken.getUsername(), netdiskAccessToken.getPassword());
            } else {
                //匿名访问，用户名密码随便给一个
                ftpClient.login("anonymous", "anonymous");                
            }
            
            int replyCode = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                throw new KumaoException("FTP服务器连接失败");
            }

            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            
            //判断文件是否存在
            FTPFile[] fileList = ftpClient.listFiles(encodeFileUri);
            if(fileList == null || fileList.length <= 0) {
                System.out.println("未找到该文件");
                throw new KumaoNetdiskFileNotFoundException("未找到该文件");
            }
            
            //下载文件
            //创建文件输出流
            if (OfflineDownloadUtils.getTaskProgressState(taskId) == ConstValue.OD_TASK_STATE_GOING) {
                //先创建文件夹，防止文件夹不存在报错
                File tempFile = new File(offlineDownloadTask.getFileSavePath());
                if (!tempFile.exists()) {
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdirs();
                    }
                }
                fos = new FileOutputStream(offlineDownloadTask.getFileSavePath());
            }
            if(fos != null) {
                final long totalSize = Long.parseLong(offlineDownloadTask.getFileSize());
                CountingOutputStream cos = new CountingOutputStream(fos){
                    protected void beforeWrite(int n){
                        super.beforeWrite(n);
                        //System.out.println(getCount() + "/" + totalSize);
                        progress.onProgress((long) getCount(), totalSize);
                    }
                };
                boolean isDown = ftpClient.retrieveFile(encodeFileUri, cos);
                if(!isDown) {
                    throw new KumaoException("下载失败");
                } 
            }
        } catch (Exception e) {
            //e.printStackTrace();
            throw e;
        } finally {
            if(fos != null) {
                fos.close();
            }
            if(ftpClient != null) {
                ftpClient.logout();
            }
        }
    }
    
    //上传文件
    public static void upload(BreakpointUploadTask breakpointUploadTask, NetdiskAccessToken netdiskAccessToken) throws Exception {
        FTPClient ftpClient = null;
        FileInputStream fis = null;
        try {
            String fileUri = breakpointUploadTask.getFileUri();
            String encodeFileUri = EncodeUtils.encodeFTPPath(fileUri);
            
            String netdiskUrl = netdiskAccessToken.getNetdiskUrl();
            netdiskUrl = netdiskUrl.replace("ftp://", "");
            String[] urlContent = netdiskUrl.split(":");
            ftpClient = new FTPClient();
            ftpClient.connect(urlContent[0], Integer.parseInt(urlContent[1]));
            
            //判断是匿名访问还是用户名密码
            if(netdiskAccessToken.getTokenType() == ConstValue.TOKEN_TYPE_USERNAME_PASSWORD) {
                //用户名密码登录
                ftpClient.login(netdiskAccessToken.getUsername(), netdiskAccessToken.getPassword());
            } else {
                //匿名访问，用户名密码随便给一个
                ftpClient.login("anonymous", "anonymous");                
            }
            
            int replyCode = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                throw new KumaoException("FTP服务器连接失败");
            }
            //上传文件
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            fis = new FileInputStream(breakpointUploadTask.getFileServerPath());
            //获取文件目录和文件名
            /*String parentFile = MyFileUtils.getFileParentDir(encodeFileUri);
            String filename = new File(encodeFileUri).getName();
            //输入流
            ftpClient.changeWorkingDirectory(parentFile);*/
            boolean result = ftpClient.storeFile(encodeFileUri, fis);
            System.out.println("上传结束");
            if(!result) {
                throw new KumaoException("上传文件失败");
            }
        } catch (Exception e) {
            //e.printStackTrace();
            throw e;
        } finally {
            if(fis != null) {
                fis.close();
            }
            if(ftpClient != null) {
                ftpClient.logout();
            }
        }
    }
}
